import __DB__               from '../db/index.js';
import __canvas__           from '../canvas/index.js';
import __customEvent__      from '../customEvent/index.js';
import __cntMenu__          from '../cntMenu/index.js';
import __node__             from '../node/index.js';
import __line__             from '../line/index.js';
import __drag__             from '../drag/index.js';
import __automatic__        from '../line/automatic.js';
import __formateHawkEye__   from '../formate/hawkEye.js';
import __opt__              from '../opt/index.js';

class apiClass{
    constructor(){

    }

    // 设置数据集
    setNodes(res){
        /*
            items:[]        // 节点集
            fn:()=>{}       // 回调函数
            recode:false    // 是否标记至操作事件
        */
        let items   = res.items||null,
            fn      = res.fn||function(){},
            recode  = res.recode||false;

        if(!items)return;
        if(!(items instanceof Array))return;
        if(items.length === 0)return;
        let nodes = items.map(item=>{
            let pull = {
                l:{
                    show:false,
                    plus:false,
                    has:false,
                },
                r:{
                    show:false,
                    plus:false,
                    has:false,
                }
            }
            if(item.pull)pull = {...pull,...item.pull};
            let obj = {
                id                  : item.id,                              // 节点ID
                pid                 : item.pid||null,                       // 父节点ID
                root                : item.root||false,                     // 是否是根节点
                flip                : item.flip||false,                     // 就否反转
                label               : item.label,                           // 标题
                type                : item.type||"tree",                    // 物理类型
                show                : item.show === false?false:true,       // 是否显示
                nodeType            : item.nodeType||"rule",                // 逻辑类型
                html                : item.html||"",                        // 自定义额外内容
                data                : item.data||"",                        // 自定义数据
                status              : item.status||-1,                      // 节点状态-1：无，0：失败，1：进行重，2：成功
                nodeLimit           : item.nodeLimit,                       // 节点宽度
                priority            : item.priority||1,                     // 优先级
                divClass            : item.divClass||[],                    // 优先级
                divColor            : item.divColor||[],                    // 自定义字体颜色
                divBgColor          : item.divBgColor||[],                  // 自定义背景字体颜色
                // 是否展开
                pull,
                offset              : item.offset||{x:null,y:null},         // 距离root的偏移量，应对不同分辨率下自由节点的位置问题，自由节点的位置由根节点减去偏移量获取
            };

            return obj;
        });

        __DB__.setNodes(nodes);

        typeof fn==='function'&&fn();
    
        if(recode){
            // 绑定自定义事件
            __customEvent__.set({
                type:"nodeUpdata",
                data:{}
            });
        }
        
    }

    // 获取节点集
    getNodes(){
        let nodes = __DB__.getAllNodes();
        
        let newNodes = nodes.map(item=>{
            let obj = {
                id                  : item.id,                      // 节点ID
                pid                 : item.pid,                     // 父节点ID
                root                : item.root,                    // 是否是根节点
                flip                : item.flip,                    // 就否反转
                label               : item.label,                   // 标题
                type                : item.type,                    // 物理类型
                show                : item.show,                    // 是否显示
                nodeType            : item.nodeType,                // 逻辑类型
                html                : item.html,                    // 自定义额外内容
                data                : item.data,                    // 自定义数据
                status              : item.status,                  // 节点状态-1：无，0：失败，1：进行重，2：成功
                nodeLimit           : item.style.limit,             // 节点宽度
                priority            : item.style.priority,          // 优先级
                pull                : item.pull,                    // 是否展开
                nodeGroup           : item.nodeGroup,               // 节点层级数
                maxGroup            : item.maxGroup,                // 节点最大层级数
                group               : item.group,
                divColor            : item.divColor,                // 自定义字体颜色
                divBgColor          : item.divBgColor,              // 自定义背景字体颜色
                offset              : item.offset,                  // 距离root的偏移量，应对不同分辨率下自由节点的位置问题，自由节点的位置由根节点减去偏移量获
            };

            return obj;
        })

        return newNodes;
    }

    // 获取单个节点
    getNode(id){
        let item = __DB__.get(id);
        let newNodes =  {
            id                  : item.id,                      // 节点ID
            pid                 : item.pid,                     // 父节点ID
            root                : item.root,                    // 是否是根节点
            flip                : item.flip,                    // 就否反转
            label               : item.label,                   // 标题
            type                : item.type,                    // 物理类型
            show                : item.show,                    // 是否显示
            nodeType            : item.nodeType,                // 逻辑类型
            html                : item.html,                    // 自定义额外内容
            data                : item.data,                    // 自定义数据
            status              : item.status,                  // 节点状态-1：无，0：失败，1：进行重，2：成功
            nodeLimit           : item.style.limit,             // 节点宽度
            priority            : item.style.priority,          // 优先级
            pull                : item.pull,                    // 是否展开
            maxGroup            : item.maxGroup,
            group               : item.group,
            offset              : item.offset,                  // 距离root的偏移量，应对不同分辨率下自由节点的位置问题，自由节点的位置由根节点减去偏移量获
            init                : item.node.init,               // 节点详细数据
        };

        return newNodes;
    }

    // 更新单个节点
    updateNode(res,hasEvt=true){
        /*
            使用说明
            updateNode({
                id:"",
                ……
            })
            可更新属性
            label       : 标题
            nodeType    : 逻辑类型
            priority    : 优先级
            status      : 节点状态
            html        : 自定义额外内容
            nodeLimit   : 节点宽度
            divClass    : 自定义样式
            divColor    : 自定义字体颜色
            divBgColor  : 自定义背景字体颜色
        */
        if(!res || !res.id)return;
        __DB__.update(res.id,res,hasEvt);
    }

    // 清除所有状态
    clearStatus(){
        let nodes = __DB__.getAllNodes();
        for(let el of nodes){
            this.updateNode({
                id:el.id,
                status:-1,
            })
        }
    }

    // 设置右键选项
    setContentMenu(res){
        /*
            使用说明
            res:{
                type:"canvas",// 类型（canvas、node）
                items:[
                    {label:"",id:"",name:"canvas",line:"down",icon:"",fn:(res)=>{}},
                    {label:"",id:"",name:"canvas",line:"down",icon:"",children:[
                        {label:"",id:"",name:"canvas",icon:"",pid:"",line:"down"},
                    ]}
                ],
            }

            id 
            pid
            label       选项名称
            name        所属面板
            line        分割线 down和up
            icon        图标
            fn          回调函数
            children    二级
        */
        __cntMenu__.initList(res);
    }

    // 定位到根节点
    localRoot(){
        __canvas__.localRoot();
    }
    
    // 添加节点
    addNode(item){
        /*
            使用说明
            id                  : item.id,                  // 必填-节点ID
            pid                 : item.pid||null,           // 必填-父节点ID
            root                : item.root||false,         // 是否是根节点
            flip                : item.flip||false,         // 就否反转  
            label               : item.label,               // 必填-标题
            type                : item.type||"tree",        // 物理类型
            show                : true,                     // 是否显示
            nodeType            : item.nodeType||"rule",    // 逻辑类型
            html                : item.html||"",            // 自定义额外内容
            data                : item.data||"",            // 自定义数据
            fn                  : item.fn||()=>{}           // 回调函数
        */
        if(!item || typeof item !== "object")return false;
        let obj = {
            id          : item.id||null,
            pid         : item.pid||null,
            root        : false,
            flip        : item.flip||false,
            label       : item.label||"新节点",
            type        : item.type||"tree",
            show        : true,
            nodeType    : item.nodeType||"rule",
            node        : {},
            html        : item.html||"",
            data        : item.data||"",
        }

        let fn = typeof item.fn === 'function'?item.fn:()=>{};

        if(!item.id)return false;
        if(!item.pid)return false;

        let sign = __node__.add(obj);
        if(sign)fn();

        // 绑定自定义事件
        __customEvent__.set({
            type:"nodeAdd",
            data:{}
        });

    }

    // 删除节点
    delNode(item){
        /*
            使用说明
            删除节点
            item={
                id:"",// 需要删除的节点id
                fn:()=>{},// 删除后的回调
            }
        */
        let id = item.id;
        let rb = {
            msg:"success"
        }

        let fn = typeof item.fn === 'function'?item.fn:()=>{};

        if(!__DB__.get(id)){
            rb.msg = "fail";
            if(fn && typeof fn)item.fn(rb);
            return;
        }

        let sign = __node__.del(id);
        if(sign)fn(rb);

        // 绑定自定义事件
        __customEvent__.set({
            type:"nodeDel",
            data:{}
        });
    }

    // 创建拖拽节点
    createdDragNode(res){
        /*
            使用说明
            createdDragNode({
                id,         // 必填
                label,      // 必填
                e,          // 必填-dom元素
                nodeType,   // 节点类型，默认为rule
                data,       // 额外信息，非必填
            })
        */
        __drag__.outsideModule(res); 
    }

    // 节点显示/隐藏加载中
    nodeLoading(res){
        __node__.loading(res);
    }

    // 开启/关闭编辑
    switchEdit(sign=true){
        __DB__.edit = sign;
    }

    // 鹰眼  open pid
    hawkEye(open,pid){
        if(typeof open !== 'boolean'){
            console.error('hawEye 第一个参数必须是boolean');
            return;
        }
        __canvas__.hawkEyeObj.open = open;
        __canvas__.hawkEyeObj.pid  = pid;
        __canvas__.hawkEye();

        __formateHawkEye__.init(__DB__.getAllNodes());    // 鹰眼-初始化
    }

    // 刷新
    refresh(){
        __DB__.reset();
    }

    // 缩放
    setZoom(res){
        /*
            setZoom(res)
                res 
                    enlarge  放大
                    narrow   缩小
                    1        0.4 < 2
        */
        if(!res)return;

        if(res === 'enlarge'){
            fn_enlarge();
            return;
        }

        if(res === 'narrow'){
            fn_narrow();
            return;
        }

        if(typeof res === 'number'){
            if(res >= 0.2 && res <= 2){
                let scale = parseFloat(res);
                __canvas__.setScale(scale);
            }
        }

        function fn_enlarge(){
            let scale = parseFloat($scale);
            scale += 0.1;
            scale = scale.toFixed(1);
            if(scale > 2){
                scale = 2;
                return
            };
            __canvas__.setScale(scale);
        }

        function fn_narrow(){
            let scale = parseFloat(scale);
            scale -= 0.1;
            scale = scale.toFixed(1);
            if(scale < 0.2){
                scale = 0.2;
                return
            };

            __canvas__.setScale(scale);
        }
    }

    // 获取缩放值
    getZoom(){
        return __canvas__.getScale();
    }

    // 展开/收起节点
    /*
        pullNode({
            id  :'',                  // 必填-节点ID
            name:'childrenPull',    // 扩展功能，目前只有'childrenPull'：深级处理
            flip:'auto'/true/false, // 操作区域是否翻转，两种类型，字符串和布尔
            pull:'auto'/true/false, // 收起和展开，两种类型，字符串和布尔
        })
    */
    pullNode(res){
        let id = res.id,
            flip = res.flip==null?'auto':res.flip,
            pull = res.pull==null?'auto':res.pull,
            name = res.name||'';
        __opt__.pullNode(id,flip,name,pull);
    }

    // 展开/收起节点-高级
    /*
        setPull({
            type:'all'/1,           // 必填-两种类型，all：全部；数字类型：层级
            name:'childrenPull',    // 扩展功能，目前只有'childrenPull'：深级处理
            flip:'auto'/true/false, // 操作区域是否翻转，两种类型，字符串和布尔
            pull:'auto'/true/false, // 收起和展开，两种类型，字符串和布尔
        })
    */
    setPull(res){
        if(!res || typeof res !== 'object' || res instanceof Array)return;
        __opt__.setPull(res)
    }

    // 创建关联线：需要配合右键菜单使用
    contactLine(id){
        if(!id)return;
        __automatic__.isDraw = true;
        __automatic__.startId = id;

        __automatic__.drawDirectionLine({
            id,
            xy:[__cntMenu__.x,__cntMenu__.y]
        });
    }

    // 选中关联线
    contactLineChecked(res){
        let s = res.startId,
            e = res.endId;
        // if(!s || !e)return;
        
        __automatic__.checkedLine(s,e);
    }

    // 绘制关联线
    drawContactLine(res,hasEvt=true){
        let s = res.startId,
            e = res.endId;
        if(!s || !e)return;

        if(!__DB__.get(s) || !__DB__.get(e))return;

        __automatic__.startId = s;
        __automatic__.endId = e;
        
        __automatic__.contect({
            nodes   : __DB__.getAllNodes(),
            canvas  : document.getElementById('automaticConnection')
        })

        if(!hasEvt)return;
        // 绑定自定义事件
        __customEvent__.set({
            type:"contactLineEvt",
            data:{
                startId     : res.id,
                endId       : res.id,
            }
        });

        __customEvent__.set({
            type:"undoRedoOpt",
            data:{}
        });
    }

    // 删除关联线
    delContactLine(res,hasEvt=false){
        let s = res.startId,
            e = res.endId;
        if(!s || !e)return;

        __automatic__.delLine(s,e);

        if(!hasEvt)return;
        __customEvent__.set({
            type:"undoRedoOpt",
            data:{}
        });
    }

    // 取消关联
    cancelContactLine(){
        __automatic__.cancelDirectionLine();
    }

    // 清空关联线
    clearConTactLine(){
        __automatic__.clear();
    }

    // 
    setUndoRedoOpt(){
        __customEvent__.set({
            type:"undoRedoOpt",
            data:{}
        });
    }

    // 高亮部分节点
    highlightNodes(items){
        __line__.lines.forEach(el=>{
            el.execute = false;
            el.color   = "";
        });

        __automatic__.hideLineAll();

        if(!items || items.length === 0)return;

        let lines = __line__.lines;
        let automaticLines = __automatic__.pathsOnlyName;

        formatLines(items,lines);
        
        formatLines2.call(this,items,automaticLines);

        function formatLines(arr1,arr2){
            
            let arr = [];
            arr1.forEach(el_1=>{
                for(let el_2 of arr1){
                    if(el_1.id === el_2.id)continue;

                    arr.push({
                        s:el_1.id,
                        e:el_2.id
                    })
                }
            })

            arr.forEach(el1=>{
                let s = el1.s,
                    e = el1.e;

                for(let el2 of arr2){
                    if(s === el2.s.id && e === el2.e.id){
                        el2.execute = true;
                        el2.color   = "#fb685c";
                        break;
                    }
                }
            })
        }

        function formatLines2(arr1,arr2){
            let arr = [];
            arr1.forEach(el_1=>{
                for(let el_2 of arr1){
                    if(el_1.id === el_2.id)continue;

                    arr.push({
                        s:el_1.id,
                        e:el_2.id
                    })
                }
            })

            

            arr.forEach(el1=>{
                let s = el1.s,
                    e = el1.e;

                for(let el2 of arr2){
                    if(s === el2.s && e === el2.e){
                        __automatic__.showLine(s,e);
                        break;
                    }
                }
            })
        }

        line_draw();

        const nodes = document.querySelectorAll(".xmd-node");
        if(nodes.length === 0)return;
        for(let el of nodes){
            let cls_el = el.getAttribute('class');
            if(cls_el.indexOf('xmd-node-highlight-'+__DB__.get(el.id).type) > -1){
                el.classList.remove('xmd-node-highlight-'+__DB__.get(el.id).type);
            }
        }

        if(items.length === 0)return;

        items.forEach(el=>{
            let parentNode = document.getElementById(el.id)
            parentNode.classList.add("xmd-node-highlight-"+__DB__.get(el.id).type);
        });


        // 绘制线
        function line_draw(){
            $e = document.getElementById('canvas');
            let w = $e.getBoundingClientRect().width;
            let h = $e.getBoundingClientRect().height;

            let colors = $init.style.line.colors;// 颜色配置
            
            let len = colors.length;
            let lineSize = $init.style.line.size;
            let html = '';
            __line__.lines.forEach(el=>{
                // 临时写的
                let color = colors[__format__.num];

                if(el.execute)color=el.color;
                if(len > 1){
                    if(__format__.num === len - 1){
                        __format__.num = 0;
                    }
                    else{
                        __format__.num++;
                    }
                }

                let line = __format__.line_path(el);
                html += `
                    <path
                        fill="none"
                        stroke="${color}"
                        opacity="1"
                        stroke-width="${lineSize}"
                        pointer-events="stroke"
                        d="${line}"
                        ></path>
                `;
            });

            let xmdSveEl = document.getElementById('automaticConnectionDirection');
            xmdSveEl.innerHTML = html;


        }

        /*__line__
            // 高亮部分节点
        highlightNodes(items){

            __DB__.lines.forEach(el=>{
                el.execute = false;
                el.color   = "";
            })

            automatic.hideLineAll();

            if(!items || items.length === 0)return;

            let lines = __DB__.lines;
            let automaticLines = automatic.pathsOnlyName;

            formatLines(items,lines);
            
            formatLines2.call(this,items,automaticLines);

            function formatLines(arr1,arr2){
                
                let arr = [];
                arr1.forEach(el_1=>{
                    for(let el_2 of arr1){
                        if(el_1.id === el_2.id)continue;

                        arr.push({
                            s:el_1.id,
                            e:el_2.id
                        })
                    }
                })

                arr.forEach(el1=>{
                    let s = el1.s,
                        e = el1.e;

                    for(let el2 of arr2){
                        if(s === el2.s.id && e === el2.e.id){
                            el2.execute = true;
                            el2.color   = "#fb685c";
                            break;
                        }
                    }
                })
            }

            function formatLines2(arr1,arr2){
                let arr = [];
                arr1.forEach(el_1=>{
                    for(let el_2 of arr1){
                        if(el_1.id === el_2.id)continue;

                        arr.push({
                            s:el_1.id,
                            e:el_2.id
                        })
                    }
                })

                

                arr.forEach(el1=>{
                    let s = el1.s,
                        e = el1.e;

                    for(let el2 of arr2){
                        if(s === el2.s && e === el2.e){
                            automatic.showLine(s,e);
                            break;
                        }
                    }
                })
            }

            line_draw();

            

            const nodes = document.querySelectorAll(".xmd-node");
            if(nodes.length === 0)return;
            for(let el of nodes){
                let cls_el = el.getAttribute('class');
                if(cls_el.indexOf('xmd-node-highlight-'+__DB__.nodes[el.id].type) > -1){
                    el.classList.remove('xmd-node-highlight-'+__DB__.nodes[el.id].type);
                }
            }

            if(items.length === 0)return;

            items.forEach(el=>{
                let parentNode = document.getElementById(el.id)
                parentNode.classList.add("xmd-node-highlight-"+__DB__.nodes[el.id].type);
            });


            // 绘制线
            function line_draw(){
                $e = document.getElementById('canvas');
                let w = $e.getBoundingClientRect().width;
                let h = $e.getBoundingClientRect().height;

                let colors = $init.style.line.colors;// 颜色配置
                
                let len = colors.length;
                let lineSize = $init.style.line.size;
                let html = '';
                __DB__.lines.forEach(el=>{
                    // 临时写的
                    let color = colors[__format__.num];

                    if(el.execute)color=el.color;
                    if(len > 1){
                        if(__format__.num === len - 1){
                            __format__.num = 0;
                        }
                        else{
                            __format__.num++;
                        }
                    }

                    let line = __format__.line_path(el);
                    html += `
                        <path
                            fill="none"
                            stroke="${color}"
                            opacity="1"
                            stroke-width="${lineSize}"
                            pointer-events="stroke"
                            d="${line}"
                            ></path>
                    `;
                });

                let xmdSveEl = document.getElementById('svg');
                xmdSveEl.innerHTML = html;


            }
        


            // __canvas__.load();
        }
        */
    }

    // 销毁
    destroyed(fn){
        __canvas__.canvas.remove();
        fn&&fn();
    }

    // 清空
    clear(fn){
        let svgAllmain = document.getElementById('xmd-svg-automatic');
        if(svgAllmain)svgAllmain.innerHTML = "";
        __canvas__.canvas.innerHTML = "";

        let automaticConnectionDirection = document.getElementById('automaticConnectionDirection');
        automaticConnectionDirection.innerHTML = "";

        let automaticConnection = document.getElementById('automaticConnection');
        automaticConnection.innerHTML = "";

        let svg = document.getElementById('svg');
        svg.innerHTML = "";
        
        let svgDirection = document.getElementById('svgDirection');
        svgDirection.innerHTML = "";
        
        fn&&fn();
    }

    // 设置居中显示
    canvasCenter(num=0){
        let nodes = __DB__.getAllNodes();
        if(nodes.length === 0)return;
        for(let el of nodes){
            if(el.left)return;
        }

        let rootW = __DB__.nodes.root.init.size.w;
        let sw  = parseInt($w_s);
        let s2w  = parseInt(sw/2);
        let arr = [];
        nodes.forEach((el,i)=>{
            arr.push({
                id:el.id,
                w:parseInt(el.init.size.w),
                x:parseInt(el.init.poi.x),
            })
        });

        arr.sort(sortData);

        let len = arr.length;
        let s = arr[0];
        let e = arr[len-1];
        let nodesMaxW = e.x - s.x + e.w;
        let outsideW = 0;
        if(s2w > nodesMaxW){
            outsideW = nodesMaxW/2;
        }
        else if(s2w < nodesMaxW && sw > nodesMaxW){
            outsideW = nodesMaxW/2;
        }
        else if(sw < nodesMaxW){
            outsideW = sw/2;
        }

        let left = parseInt($e.style.left);
        let newLeft = left  + rootW/2 - outsideW;

        if(sw< nodesMaxW){
            newLeft = newLeft + num;
        }
        else if(s2w < nodesMaxW && sw > nodesMaxW && (sw - nodesMaxW)/2 < num){
            newLeft = newLeft + num;
        }

        $e.style.left = newLeft + "px";
        

        // 排序
        function sortData(a,b){
            return a.x - b.x
        }
    }

    // 设置多选
    setNodeCheckeds(items){
        if(!items)return;
        if(!items instanceof Array)return;

        __node__.setNodeCheckeds(items);
    }

    // 获取多选
    getNodeCheckeds(){
        return __node__.getNodeCheckeds();
    }

    // on 操作回调事件---
    on(eventName,fn){
        if(!eventName)return;
        __customEvent__.on(eventName,fn);
    }

    // off 注销事件
    off(eventName){
        __customEvent__.off(eventName);
    }
}

export default apiClass;